package de.tu_darmstadt.gdi1.xcom.tests.testcases.students;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel1;

/**
 * 
 * Tests if mouseclicks on the gamearea are processed correctly.
 * 
 * @author Lukas Schwoebel
 *
 */
public class MouseclickTest {
	
	private XcomTestAdapterLevel1 testAdapter;
	private XcomTestAdapterLevel1 testAdapterMouse;
	
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		testAdapter = new XcomTestAdapterLevel1();
		testAdapterMouse = new XcomTestAdapterLevel1();
	}

	/**
	 * Test method for {@link de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel1#clickPerformedAt()}.
	 */
	@Test
	public final void testProcessCorrectly() {
		testAdapter.loadLevelFromString(TestLevel.testLevel);

		// do mouseclick so the player turns east
		testAdapter.clickPerformedAt(8, 2);
		assertEquals("After click at 8:2 player should look East", 2, testAdapter.activePlayerLookingToDirection());
		

		String expectedLevel1 = "" +
			"############\n" +
			"##...#######\n" +
			"##ZZ@##...##\n" +
			"###.###Z..##\n" +
			"###.####.###\n" +
			"#.@..##Z..##\n" +
			"#...@....Z##\n" +
			"############";

		String expectedLevel2 = "" +
			"############\n" +
			"##...#######\n" +
			"##ZZ@##...##\n" +
			"##..###Z..##\n" +
			"#c#.####=###\n" +
			"#.@..##Z..##\n" +
			"#...@....Z##\n" +
			"############";
		
		// do again and make sure player is not walking into the wall
		testAdapter.clickPerformedAt(8, 2);
		String levelString = testAdapter.levelRepresentationAsString();
		boolean expectedLevelReturned = (expectedLevel1.equals(levelString)) || (expectedLevel2.equals(levelString));
		assertTrue("Player should not walk into the wall or do anything, " + levelString, expectedLevelReturned);

		// turn south
		testAdapter.clickPerformedAt(4, 5);
		assertEquals("After click at 4:5 player should look South", 3, testAdapter.activePlayerLookingToDirection());

		// turn west
		testAdapter.clickPerformedAt(0, 2);
		assertEquals("After click at 0:2 player should look West", 4, testAdapter.activePlayerLookingToDirection());

		// do again and make sure player is attacking
		testAdapter.clickPerformedAt(0, 2);
		
		expectedLevel1 = "" +
			"############\n" +
			"##...#######\n" +
			"##Z.@##...##\n" +
			"##..###Z..##\n" +
			"###.####.###\n" +
			"#.@..##Z..##\n" +
			"#...@....Z##\n" +
			"############";

		expectedLevel2 = "" +
			"############\n" +
			"##...#######\n" +
			"##Z.@##...##\n" +
			"##..###Z..##\n" +
			"#c#.####=###\n" +
			"#.@..##Z..##\n" +
			"#...@....Z##\n" +
			"############";

		levelString = testAdapter.levelRepresentationAsString();
		expectedLevelReturned = (expectedLevel1.equals(levelString)) || (expectedLevel2.equals(levelString));
		assertTrue("After click at 0:2 player should have attacked the enemy\n" + levelString, expectedLevelReturned);		
	}
	/**
	 * Test method for {@link de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel1#clickPerformedAt()}.
	 */
	@Test
	public final void testMouseactionAreCorrectlyMapped() {
		// load testlevel in both adapters
		testAdapter.loadLevelFromString(TestLevel.testLevel);
		testAdapterMouse.loadLevelFromString(TestLevel.testLevel);
		
		// do some actions, once by "mouse" and once by "keyboard"
		// compare actionpoints of both adapters
		
		// move action
		testAdapter.performActionForActivePlayer();
		testAdapterMouse.clickPerformedAt(4, 1);
		
		assertEquals("A mouseclick-walkingaction should cost the same as the keyboard-action", testAdapter.actionPointsLeft(), testAdapterMouse.actionPointsLeft());
		
		// rotation action
		testAdapter.rotateActivePlayer(false);
		testAdapterMouse.clickPerformedAt(1, 1);
		assertEquals("A mouseclick-rotation should cost the same as the keyboard-action", testAdapter.actionPointsLeft(), testAdapterMouse.actionPointsLeft());
		assertEquals("A rotation performed by mouse should have the same result as by keyboard", testAdapter.activePlayerLookingToDirection(), testAdapterMouse.activePlayerLookingToDirection());
	}
}
